home *** CD-ROM | disk | FTP | other *** search
/ Hardcore Gamer Resource Kit / Hardcore Gamer Resource Kit - Disc 3.iso / screensavers / saver04.zip / track2.c < prev    next >
C/C++ Source or Header  |  1997-07-16  |  58KB  |  2,164 lines

  1. #define GO
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include <float.h>
  6. #include <time.h>
  7. #include <string.h>
  8. #include <search.h>
  9.  
  10. #include <glide.h>
  11.  
  12. #define Float2Int (int)
  13. #define Int2Float (double)
  14.  
  15.  
  16. #define BOTTOM 479 
  17. #define RIGHT  639 
  18. #define FOV    128 
  19.  
  20. #define PI 3.141592654
  21. #define TRUE 1
  22. #define FALSE 0
  23.  
  24. #define TICK (double)0.3
  25. #define DAMP (double)0.99
  26. #define SLEEP 0
  27. #define WATER 30
  28.  
  29. #define SURFACE 0
  30. #define BLOB    1
  31. #define MASK    2
  32. #define CMASK   3
  33.  
  34. #define MAXVERTEX       750
  35. #define MAXFACE         1400
  36.  
  37. extern    short int  VERTEX,FACE;    
  38. extern    short int  fobject[MAXVERTEX][3];
  39. extern    short int pt[MAXVERTEX][4],facet[MAXFACE][3],current_bin;
  40. extern int facevert, facepoly;
  41.  
  42. extern void loadobject ();
  43.  
  44.  
  45.  
  46. int mode;
  47.  
  48. long sqrttab[0x100]; // declare table of square roots
  49. long isqrttab[0x100]; // declare table of square roots
  50.  
  51. GrMipMapId_t facetexture,
  52.              texture1,
  53.              texture2,
  54.              texture3,
  55.              texture4,
  56.              texture5,
  57.              texture6,
  58.              spotlight,
  59.              cockpit;
  60.  
  61.  
  62. GrMipMapId_t *fgtexture;
  63. GrMipMapId_t *bgtexture;
  64.  
  65.  
  66.  
  67. GrHwConfiguration hwconfig;
  68. GrColorCombineFnc_t cc_fnc;
  69. GrScreenResolution_t    screenRes;
  70.  
  71. float wWidth = 640.0f;
  72. float wHeight = 480.0f;
  73.  
  74. double V        [32][32];
  75. double Fc       [32][32]; /* Centering Force */
  76. double Fn       [32][32]; /* Neihboring Force */
  77.  
  78.  
  79.  
  80.   typedef struct {
  81.      double  x, y, z;
  82.  } point;
  83.  
  84.  typedef struct {
  85.      point     pt[3];    /* Vertices of triangle */
  86.      double    area;     /* Unused; might be used for adaptive subdivision */
  87.  } triangle;
  88.  
  89.  typedef struct {
  90.      int       npoly;    /* # of triangles in object */
  91.      triangle *poly;     /* Triangles */
  92.  } object;
  93.  
  94. int gid; /* Global Object id */
  95.  
  96.  
  97. unsigned char *screen; 
  98. char screen_buff[640*480];
  99. int max = 10; 
  100. unsigned int ADDR; 
  101. int width,height; 
  102. char filename[80]; 
  103. int debug; 
  104. int count; 
  105. FILE* fp; 
  106. int bad; 
  107.  
  108. /* Camera POV */ 
  109. double cx,cy,cz; 
  110. int    theta; 
  111.  
  112. int ltheta; 
  113. int rtheta; 
  114. int ftheta; 
  115. double tpx,tpy; /* Test points */ 
  116. double axl,byl,cl; 
  117. double axr,byr,cr; 
  118. double axf,byf,cf; 
  119. double lsign, rsign, fsign; 
  120.  
  121.  
  122.  /*----- constants*/ 
  123. #define MAXDEGREES 1024 
  124. #define EYE_DISTANCE Int2Fixed(256) 
  125. #define MAXVERTICES 2000 
  126. #define MAXPOLYGONS 2100 
  127. #define MAXPOLYVERT 3
  128.  
  129. double Fcb [MAXVERTICES];
  130. double Vb  [MAXVERTICES];
  131. double Fnb [MAXVERTICES];
  132.  
  133. /*----- these are for the gouraud shading routines ----*/ 
  134. int ledge_x[480]; /* x coordinate for left edge*/ 
  135. int ledge_color[480]; /* color for left edge*/ 
  136.  
  137. int redge_x[480]; /* destination x coordinate for right edge*/ 
  138. int redge_color[480]; /* color for right edge*/ 
  139.  
  140. /*----- these are for the basic graphics routines*/ 
  141. int ytable[480]; /* so u can do ytable[y]+x (fast), instead of y*320+x (slow)*/ 
  142.  
  143.  
  144. /*----- 16.16 fixedpoint trig lookup tables*/ 
  145. double cosine[MAXDEGREES]; /* cosine lookup table*/ 
  146. double sine[MAXDEGREES];  /* sine lookup table*/ 
  147. double polar_lut [MAXDEGREES]; /* LUT for sin/cos theta near x-axis */ 
  148. double dsine [MAXDEGREES]; 
  149. double dcosine [MAXDEGREES]; 
  150.  
  151. /*----- angle and position of 3d object*/ 
  152. int xangle,yangle,zangle; /* angles of rotation*/ 
  153. double xpos,ypos,zpos; /* position of object in 3d*/ 
  154.  
  155.  
  156. /* structure of one vertex*/ 
  157. typedef struct 
  158.   double s,t;      /* Texture co-ordinates */
  159.   double ox,oy,oz; /* vertex original coordinates*/ 
  160.   double wx,wy,wz; /* vertex working coordinates*/ 
  161.   double Nox,Noy,Noz; /* vertex normal original coordinatesv*/ 
  162.   double SNox,SNoy,SNoz; /* vertex normal original coordinates - blob*/ 
  163.   double xlen,ylen,zlen;
  164.   int    vcount;
  165.   double Nwx,Nwy,Nwz; /* vertex normal working coordinates*/ 
  166.   int sx,sy,sz; /* vertex screen coordinates*/ 
  167.   int color; /* color of vertex normal*/ 
  168. } VertexTYPE; 
  169.  
  170. /* structure of one polygon*/ 
  171. typedef struct 
  172.   int texture_type ; /* 0 = flat colour, 1 = Gouraud, 2 = Texture */ 
  173.   int NumOfVertices; /* number of vertices that make up the polygon*/ 
  174.   int Vertex[MAXPOLYVERT]; /* vertex indices in counter clockwise order*/ 
  175.   int zcenter; /* for sorting*/ 
  176.   double Nox,Noy,Noz; /* polygon normals (only used for ver normals)*/ 
  177. } PolygonTYPE; 
  178.  
  179. /* object structure*/ 
  180. typedef struct 
  181.   double Ox,Oy,Oz; /* coordinates of object's origin*/ 
  182.   int Ax,Ay,Az; /* object's rotation angles*/ 
  183.   int NumOfVertices; /* number of vertices in object*/ 
  184.   VertexTYPE Vertex[MAXVERTICES]; /* all vertices in object*/ 
  185.   int NumOfPolygons; /* number of polygons in object*/ 
  186.   PolygonTYPE Polygon[MAXPOLYGONS]; /* all polygons in object*/ 
  187. } ObjectTYPE; 
  188.  
  189. ObjectTYPE Object; /* one object - THIS IS THE WATER */ 
  190.  
  191. /* structure of light source*/ 
  192. typedef struct 
  193.   double x,y,z; /* coodinates of light source*/ 
  194.   double wx,wy,wz; /* working (intermediate) coordinates*/ 
  195.   int ax,ay,az; /* rotation angles*/ 
  196. } LightSourceTYPE; 
  197.  
  198. LightSourceTYPE LightSource; /* one light source*/ 
  199.  
  200. int NumOfSortedPolygons; /* number of sorted visible polygons*/ 
  201. int NumOfViewedPolygons; /* number of sorted visible polygons*/ 
  202. int PolygonOrderList[MAXPOLYGONS]; /* list of polygon indices for qsorting*/ 
  203. int PolygonOrderClip[MAXPOLYGONS]; /* list of polygon indices for qsorting*/ 
  204. int PolygonViewList[MAXPOLYGONS];  /* list of polygon indices in view */ 
  205. int PolygonViewClip[MAXPOLYGONS];  /* list of polygon indices in view */ 
  206.  
  207.  
  208.  
  209. double xpath[MAXVERTICES]; 
  210. double ypath[MAXVERTICES]; 
  211. double zpath[MAXVERTICES]; 
  212. int    thetapath[MAXVERTICES]; 
  213.  
  214.  
  215. /*---------------------- function prototypes ------------------------*/ 
  216. int main(int argc,char**argv); 
  217. int  Visible (); 
  218. void CalcViewTriangle(); 
  219. void Demo(); 
  220.  
  221. void DrawGouraudPolygon(PolygonTYPE *poly);
  222. void plot_tri_3dfx();
  223. void plot_poly_3dfx();
  224. void plot_bg();
  225. void bench();
  226.  
  227. int  Load3dfxTexture();
  228.  
  229. void InitYTable(void); 
  230. void InitTrigTables(void); 
  231. void ClearVertexList(); 
  232. void Random(); 
  233. void RotatePoints(); 
  234. void RotateNormals(); 
  235. void DrawObject(); 
  236. void MakeViewPolygonList(); 
  237. void MakeCulledPolygonList(); 
  238. void SortPolygonList(); 
  239. int _cdecl ComparePolygons(const void *a, const void *b);
  240. void InitLightSource(void); 
  241. void CalculateColor(); 
  242. void identity(); 
  243. void multiply(); 
  244.  
  245.  
  246. /*-------------------------------------------------------------------*/
  247.  
  248.  
  249.  
  250.  
  251. int
  252. DoFace()
  253. {
  254. object *obj;
  255. int i,j,k,found;
  256. double x,y,z;
  257. double max=-99999.9,min=99999.9;
  258.  
  259.   loadobject();
  260.  
  261.  
  262.   Object.NumOfVertices = 0;
  263.   Object.NumOfPolygons = 0;
  264.  
  265.   for (i=0;i<MAXVERTICES;i++)
  266.     Object.Vertex[i].ox = 0;
  267.  
  268.   /* For all poly's in list extract vertices  */
  269.   for (i=0;i<facevert;i++)
  270.   {
  271.       z = (double)fobject[i][0]/4.0;
  272.       y = (double)fobject[i][1]/4.0;
  273.       x = (double)fobject[i][2]/4.0;
  274.       
  275.       k = 0;
  276.       found = FALSE;
  277.       while (k<Object.NumOfVertices && found == FALSE)
  278.       {
  279.         if (Object.Vertex[k].ox == x &&
  280.             Object.Vertex[k].oy == y &&
  281.             Object.Vertex[k].oz == z ) 
  282.          found = TRUE;
  283.         else 
  284.           k++;
  285.       }
  286.    
  287.       /* add vertex to list */
  288.       if (found == FALSE)
  289.       {
  290.         Object.Vertex[k].ox = x;
  291.         Object.Vertex[k].oy = y;
  292.         Object.Vertex[k].oz = z;
  293.  
  294.         Object.Vertex[k].s = 137.0 +(127.0/40.5) *z; /* Adjust height wise */
  295.         Object.Vertex[k].t = 201.0 +(127.0/37.0) * -x; /* Adjust width wise */
  296.  
  297.         Object.NumOfVertices ++;
  298.         
  299.       }
  300.     }
  301.  
  302.   
  303.   printf("Unique vertices = %d (%d) \n",
  304.          Object.NumOfVertices,3*facevert);
  305.  
  306.   x = y = z = 0.0;
  307.   for (i=0;i<Object.NumOfVertices;i++)
  308.   {
  309.     x += Object.Vertex[i].ox;
  310.     y += Object.Vertex[i].oy;
  311.     z += Object.Vertex[i].oz;
  312.   }
  313.   x=x/(double)Object.NumOfVertices;
  314.   y=y/(double)Object.NumOfVertices;
  315.   z=z/(double)Object.NumOfVertices;
  316.  
  317.   printf("Average = %f %f %f\n",x,y,z);
  318.   
  319.   for (i=0;i<Object.NumOfVertices;i++)
  320.   {
  321.     Object.Vertex[i].ox-=x;
  322.     Object.Vertex[i].oy-=y;
  323.     Object.Vertex[i].oz-=z;
  324.   }
  325.  
  326.   for (i=0;i<facepoly;i++)
  327.   {
  328.     Object.Polygon[i].Vertex[0] = facet[i][0];
  329.     Object.Polygon[i].Vertex[1] = facet[i][2];
  330.     Object.Polygon[i].Vertex[2] = facet[i][1];
  331.     
  332.     Object.Polygon[i].NumOfVertices = 3;
  333.     Object.NumOfPolygons ++;
  334.   }
  335.  
  336.   printf("Number of polys %d\n\n",Object.NumOfPolygons);
  337. }
  338.  
  339.  
  340.  
  341.  
  342. void
  343. DoSphere(int level)
  344. {
  345. object *obj;
  346. int i,j,k,found;
  347. double x,y,z;
  348. double maxx,minx;
  349.  
  350. maxx=-999.9;
  351. minx=999.9;
  352.  
  353.   obj = sphere(level);
  354.  
  355.   Object.NumOfVertices = 0;
  356.   Object.NumOfPolygons = 0;
  357.  
  358.   for (i=0;i<MAXVERTICES;i++)
  359.     Object.Vertex[i].ox = 0;
  360.  
  361.   /* For all poly's in list extract vertices  */
  362.   for (i=0;i<obj->npoly;i++)
  363.   {
  364.     for (j=0;j<3;j++)
  365.     {
  366.       x = obj->poly[i].pt[j].x*(double)20.0;
  367.       y = obj->poly[i].pt[j].y*(double)20.0;
  368.       z = obj->poly[i].pt[j].z*(double)20.0;
  369.  
  370.       found = FALSE;
  371.       k = 0;
  372.       while (k<Object.NumOfVertices && found == FALSE)
  373.       {
  374.         if (Object.Vertex[k].ox == x &&
  375.             Object.Vertex[k].oy == y &&
  376.             Object.Vertex[k].oz == z ) 
  377.          found = TRUE;
  378.         else 
  379.           k++;
  380.       }
  381.    
  382.       /* add vertex to list */
  383.       if (found == FALSE)
  384.       {
  385.         Object.Vertex[k].ox = x;
  386.         Object.Vertex[k].oy = y;
  387.         Object.Vertex[k].oz = z;
  388.  
  389.         Object.Vertex[k].s = 127.0 +(127.0/20.0) * x;
  390.         Object.Vertex[k].t = 127.0 +(127.0/20.0) * y;
  391.  
  392.         if (x > maxx) maxx = x;
  393.         if (x< minx) minx = x;
  394.  
  395.         
  396.         Object.NumOfVertices ++;
  397.       }
  398.     }
  399.   }
  400.   printf("MAX %f MIN %f \n",maxx,minx);
  401.   printf("Unique vertices = %d (%d) \n",
  402.          Object.NumOfVertices,3*obj->npoly);
  403.  
  404.  
  405.   for (i=0;i<obj->npoly;i++)
  406.   {
  407.     for (j=0;j<3;j++)
  408.     {
  409.       x = obj->poly[i].pt[j].x*(double)20.0;
  410.       y = obj->poly[i].pt[j].y*(double)20.0;
  411.       z = obj->poly[i].pt[j].z*(double)20.0;
  412.  
  413.       k = 0;found = FALSE;
  414.       while (k<Object.NumOfVertices && found == FALSE) 
  415.       {
  416.         if (Object.Vertex[k].ox == x &&
  417.             Object.Vertex[k].oy == y &&
  418.             Object.Vertex[k].oz == z ) 
  419.           found = TRUE;
  420.         else 
  421.           k++;
  422.       }
  423.       if (k == Object.NumOfVertices) printf("OH DEAR!\n");
  424.  
  425.       Object.Polygon[i].Vertex[j] = k;
  426.     }
  427.     Object.Polygon[i].NumOfVertices = 3;
  428.   }
  429.   Object.NumOfPolygons = i;
  430.  printf("Number of polys %d\n\n",Object.NumOfPolygons);
  431. }
  432.  
  433.  
  434.  
  435.  
  436. void build_table(void) {
  437.     unsigned short i;
  438.     float f;
  439.     unsigned int *fi = (unsigned*)&f;   // To access the bits of a float in
  440.                                         // C quickly we must misuse pointers
  441.     for (i = 0; i <= 0x7f; i++) {
  442.         *fi = 0;
  443.  
  444.             // Build a float with the bit pattern i as mantissa
  445.             // and an exponent of 0, stored as 127
  446.         *fi = (i << 16) | (127 << 23);
  447.         f = sqrt(f);
  448.  
  449.             // Take the square root then strip the first 7 bits of
  450.             // the mantissa into the table
  451.         sqrttab[i] = (*fi & 0x7fffff);
  452.  
  453.             // Repeat the process, this time with an exponent of 1,
  454.             // stored as 128
  455.         *fi = 0;
  456.         *fi = (i << 16) | (128 << 23);
  457.         f = sqrt(f);
  458.         sqrttab[i+0x80] = (*fi & 0x7fffff);
  459.     }
  460. }
  461.  
  462. void build_itable(void) {
  463.     unsigned short i;
  464.     float f;
  465.     unsigned int *fi = (unsigned*)&f;   // To access the bits of a float in
  466.                                         // C quickly we must misuse pointers
  467.     for (i = 0; i <= 0x7f; i++) {
  468.         *fi = 0;
  469.  
  470.             // Build a float with the bit pattern i as mantissa
  471.             // and an exponent of 0, stored as 127
  472.         *fi = (i << 16) | (127 << 23);
  473.         f = 1.0/sqrt(f);
  474.  
  475.             // Take the square root then strip the first 7 bits of
  476.             // the mantissa into the table
  477.         isqrttab[i] = (*fi & 0x7fffff);
  478.  
  479.             // Repeat the process, this time with an exponent of 1,
  480.             // stored as 128
  481.         *fi = 0;
  482.         *fi = (i << 16) | (128 << 23);
  483.         f = 1.0/sqrt(f);
  484.         isqrttab[i+0x80] = (*fi & 0x7fffff);
  485.     }
  486. }
  487.  
  488.  
  489.  
  490.     // fsqrt - fast square root by table lookup, original C version
  491. float fsqrt(float n) {
  492.     unsigned int *num = (unsigned *)&n; // to access the bits of a float in C
  493.                                         // we must misuse pointers
  494.  
  495.     short e;        // the exponent
  496.     if (n == 0) return (0); /* check for square root of 0 */
  497.     e = (*num >> 23) - 127; /* get the exponent - on a SPARC the */
  498.                             /* exponent is stored with 127 added */
  499.     *num &= 0x7fffff;   /* leave only the mantissa */
  500.     if (e & 0x01) *num |= 0x800000;
  501.                 /* the exponent is odd so we have to */
  502.                 /* look it up in the second half of  */
  503.                 /* the lookup table, so we set the high bit */
  504.     e >>= 1;    /* divide the exponent by two */
  505.                 /* note that in C the shift */
  506.                 /* operators are sign preserving */
  507.                 /* for signed operands */
  508.         // Do the table lookup, based on the quaternary mantissa,
  509.         // then reconstruct the result back into a float
  510.     *num = ((sqrttab[*num >> 16])) + ((e + 127) << 23);
  511.     return(n);
  512. }
  513.  
  514.  
  515. float fisqrt(float n) {
  516.     unsigned int *num = (unsigned *)&n; // to access the bits of a float in C
  517.                                         // we must misuse pointers
  518.  
  519.     short e;        // the exponent
  520.     if (n == 0) return (0); /* check for square root of 0 */
  521.     e = (*num >> 23) - 127; /* get the exponent - on a SPARC the */
  522.                             /* exponent is stored with 127 added */
  523.     *num &= 0x7fffff;   /* leave only the mantissa */
  524.     if (e & 0x01) *num |= 0x800000;
  525.                 /* the exponent is odd so we have to */
  526.                 /* look it up in the second half of  */
  527.                 /* the lookup table, so we set the high bit */
  528.     e >>= 1;    /* divide the exponent by two */
  529.                 /* note that in C the shift */
  530.                 /* operators are sign preserving */
  531.                 /* for signed operands */
  532.         // Do the table lookup, based on the quaternary mantissa,
  533.         // then reconstruct the result back into a float
  534.     *num = ((isqrttab[*num >> 16])) + ((e + 127) << 23);
  535.     return(n);
  536. }
  537.  
  538.  
  539.  
  540.  
  541.  
  542. int
  543. init()
  544. {
  545.   int x,y,i;
  546.  
  547.   for (x = 0; x< WATER; x++)
  548.   {
  549.     for (y=0; y<WATER; y++)
  550.     {
  551.       V [x][y] = 0.0;
  552.     }
  553.   }
  554.  
  555.    for (x = 0; x< Object.NumOfVertices; x++)
  556.     Vb [x] = 0.0;
  557.  
  558.   Vb[rand()%Object.NumOfVertices] = 7.0;
  559.   Vb[rand()%Object.NumOfVertices] = 7.0;
  560.  
  561.   Vb[rand()%Object.NumOfVertices] = 7.0;
  562.   Vb[rand()%Object.NumOfVertices] = 7.0;
  563.  
  564.   Vb[rand()%Object.NumOfVertices] = 7.0;
  565.   Vb[rand()%Object.NumOfVertices] = 7.0;
  566.  
  567.  
  568.  
  569.   V[WATER/2][WATER/2] = 8.0;
  570.   V[WATER/2-1][WATER/2] = 8.0;
  571.   V[WATER/2-1][WATER/2-1] = 8.0;
  572.   V[WATER/2][WATER/2-1] = 8.0;
  573.   /*V[15][15] = 5.0;*/
  574.  
  575. }
  576.  
  577.  
  578. int 
  579. calcFc(int mode)
  580. {
  581.   int x,y;
  582.   double max,roottwo;
  583.   roottwo = 1.0 / sqrt(2.0);
  584.  
  585.   max = -99999.99;
  586.  
  587.   if (mode == SURFACE)
  588.   {
  589.     for (x = 0; x< WATER; x++)
  590.     {
  591.       for (y=0; y<WATER; y++)
  592.       {
  593.         /*Fc [x][y] = Object.Vertex[x+y*WATER].ox /15.0;
  594.         Fc [x][y] = 0.1*fabs(Object.Vertex[x+y*WATER].ox) * Object.Vertex[x+y*WATER].ox;*/
  595.         Fc [x][y] = Object.Vertex[x+y*WATER].ox;
  596.       }
  597.     }
  598.  
  599.     for (x = 1; x< WATER; x++)
  600.     {
  601.       for (y=1; y<WATER; y++)
  602.       {
  603.         Fn [x][y]=(roottwo*Fc[x-1][y-1]) + Fc[x][y-1] + (roottwo*Fc[x+1][y-1])+
  604.                         Fc[x-1][y]    +   0.0*Fc[x][y] +   Fc[x+1][ y]   +
  605.                   (roottwo*Fc[x-1][y+1]) + Fc[x][y+1] + (roottwo*Fc[x+1][y+1]) ;
  606.         Fn [x][y] = Fn [x][y]/(4.0+roottwo*4.0);
  607.  
  608.         V[x][y] += TICK * (Fn[x][y] - Fc[x][y]) /* Accel */;
  609.         V[x][y] *= DAMP; /* Damping */
  610.         Object.Vertex[x+y*WATER].ox+=TICK * V[x][y];
  611.       }
  612.     }
  613.   }
  614.   else if (mode == BLOB)
  615.   {
  616.  for (x = Object.NumOfVertices-1; x>=0; x--)
  617.   {
  618.     Fcb [x] = sqrt(Object.Vertex[x].ox*Object.Vertex[x].ox + 
  619.                    Object.Vertex[x].oy*Object.Vertex[x].oy +
  620.                    Object.Vertex[x].oz*Object.Vertex[x].oz );
  621.     Object.Vertex[x].vcount = 0.0;
  622.     Fnb [x] = 0.0;
  623.   }
  624.  
  625.   /* for each polygon .. */
  626.   for (x = Object.NumOfPolygons-1; x>=0; x--)
  627.   {
  628.     for (y=2;y>=0;y--) /* for each vertex */
  629.     {
  630.       Fnb [Object.Polygon[x].Vertex[y]] += 
  631.           (Fcb[Object.Polygon[x].Vertex[(y+1)%3]] + 
  632.            Fcb[Object.Polygon[x].Vertex[(y+2)%3]])/2.0  ;
  633.  
  634. /* printf("Poly %d  Vertex %d (%d) = %f\n",
  635.         x,y,Object.Polygon[x].Vertex[y],
  636.         Fnb [Object.Polygon[x].Vertex[y]]) ; */
  637.  
  638.       Object.Vertex[Object.Polygon[x].Vertex[y]].vcount += 1.0;
  639.     }
  640.   }
  641.  
  642.   for (x = Object.NumOfVertices-1; x>=0; x--)
  643.   {
  644.     Fnb [x] = Fnb [x] / Object.Vertex[x].vcount ;
  645.  
  646. /*
  647.  printf("Fnb[%d] = %f / %f = %f\n",
  648.         x,Fnb[x],Object.Vertex[x].vcount,
  649.         Fnb[x]); 
  650. */
  651.  
  652.   /* printf("Fnb =  %lf   Fcb = %lf\n",
  653.           Fnb[x],Fcb[x]); */
  654.  
  655.       Vb[x] += TICK * (Fnb[x] - Fcb[x]) /* Accel */;
  656.       Vb[x] *= DAMP; /* Damping */
  657.       Object.Vertex[x].ox+= Object.Vertex[x].ox * ((TICK * Vb[x])/Fnb[x]);
  658.       Object.Vertex[x].oy+= Object.Vertex[x].oy * ((TICK * Vb[x])/Fnb[x]);
  659.       Object.Vertex[x].oz+= Object.Vertex[x].oz * ((TICK * Vb[x])/Fnb[x]);
  660.   }
  661.  
  662.   }
  663.     
  664. }
  665.  
  666.  
  667.  
  668.  
  669. /*----------------------------------------------------------------------*/
  670.  
  671. void InitTrigTables(void) 
  672.   int i; 
  673.   for(i=0; i<MAXDEGREES; i++) 
  674.   { 
  675.     cosine[i]=(cos((double)i*(double)360/MAXDEGREES * 
  676.             (double)3.14159265 /(double)180.0)); 
  677.     sine[i] =(sin((double)i*(double)360/MAXDEGREES * 
  678.                (double)3.14159265 / (double)180.0)); 
  679.  
  680.     dsine[i] = (sin((double)i*(double)360/MAXDEGREES * 
  681.                (double)PI/(double)180.0)); 
  682.     dcosine[i] = (cos((double)i*(double)360/MAXDEGREES * 
  683.             (double)PI/(double)180.0)); 
  684.  
  685.     if (qabs(256-i)>128 && 
  686.         qabs(768-i)>128) 
  687.       polar_lut[i] = (sin((double)i*(double)360/MAXDEGREES * 
  688.                (double)PI/(double)180.0)) / 
  689.                  (cos((double)i*(double)360/MAXDEGREES * 
  690.             (double)PI/(double)180.0)); 
  691.     else  
  692.       polar_lut[i] = (cos((double)i*(double)360/MAXDEGREES * 
  693.             (double)PI /(double)180.0)) / 
  694.                  (sin((double)i*(double)360/MAXDEGREES * 
  695.                (double)PI/(double)180.0)); 
  696.   } 
  697.  
  698. void InitYTable(void) 
  699.   int i; 
  700.   for(i=0;i<480;i++) 
  701.   { 
  702.   ytable[i]=i*640; 
  703.   } 
  704.  
  705. /*----------------------------------------------------------------------*/ 
  706.  
  707.  
  708. void FInitNormals() 
  709.   register double x1,x2,x3,y1,y2,y3,z1,z2,z3,length;
  710.   register double xlen,ylen,zlen; 
  711.   register int i,j,k; 
  712.  
  713.   /*printf(" first calculate the polygon normals\n"); */
  714.   for(i = Object.NumOfPolygons-1;i>=0 ;i--) 
  715.   { 
  716.     x1=(Object.Vertex[Object.Polygon[i].Vertex[0]].ox); 
  717.     x2=(Object.Vertex[Object.Polygon[i].Vertex[1]].ox); 
  718.     x3=(Object.Vertex[Object.Polygon[i].Vertex[2]].ox); 
  719.     y1=(Object.Vertex[Object.Polygon[i].Vertex[0]].oy); 
  720.     y2=(Object.Vertex[Object.Polygon[i].Vertex[1]].oy); 
  721.     y3=(Object.Vertex[Object.Polygon[i].Vertex[2]].oy); 
  722.     z1=(Object.Vertex[Object.Polygon[i].Vertex[0]].oz); 
  723.     z2=(Object.Vertex[Object.Polygon[i].Vertex[1]].oz); 
  724.     z3=(Object.Vertex[Object.Polygon[i].Vertex[2]].oz); 
  725.    
  726.     /* calculate perpendicular via the cross product of 1st vertex & normal*/ 
  727.     xlen = (y1-y2)*(z1-z3) - (z1-z2)*(y1-y3); 
  728.     ylen = (z1-z2)*(x1-x3) - (x1-x2)*(z1-z3); 
  729.     zlen = (x1-x2)*(y1-y3) - (y1-y2)*(x1-x3); 
  730.     
  731.     /* calculate the length of the normal*/ 
  732.     length = 1.0/sqrt(xlen*xlen + ylen*ylen + zlen*zlen); 
  733.  
  734.     /* scale it to a unit normal*/ 
  735.     if (length!=0.0) 
  736.     { 
  737.       Object.Polygon[i].Nox = (xlen * length); 
  738.       Object.Polygon[i].Noy = (ylen * length); 
  739.       Object.Polygon[i].Noz = (zlen * length); 
  740.     } 
  741.   } 
  742.  
  743.  
  744.   /*This will calculate the normals of the vertices for environment mapping*/ 
  745.   for(i= Object.NumOfVertices-1;i>=0; i--) 
  746.   { 
  747.     Object.Vertex[i].xlen = 0.0;
  748.     Object.Vertex[i].ylen = 0.0;
  749.     Object.Vertex[i].zlen = 0.0;
  750.     Object.Vertex[i].vcount = 0;
  751.   }
  752.  
  753.    
  754.   for(j = Object.NumOfPolygons-1;j>=0 ;j--) 
  755.   { 
  756.     for(k=Object.Polygon[j].NumOfVertices-1;k>=0;k--) 
  757.     { 
  758.         Object.Vertex[Object.Polygon[j].Vertex[k]].xlen += Object.Polygon[j].Nox;
  759.         Object.Vertex[Object.Polygon[j].Vertex[k]].ylen += Object.Polygon[j].Noy;
  760.         Object.Vertex[Object.Polygon[j].Vertex[k]].zlen += Object.Polygon[j].Noz;
  761.         Object.Vertex[Object.Polygon[j].Vertex[k]].vcount ++;
  762.     } 
  763.   } 
  764.    
  765.   for(i= Object.NumOfVertices-1;i>=0; i--) 
  766.   { 
  767.     if(Object.Vertex[i].vcount >0) 
  768.     { 
  769.       Object.Vertex[i].xlen=Object.Vertex[i].xlen/(double)Object.Vertex[i].vcount;
  770.       Object.Vertex[i].ylen=Object.Vertex[i].ylen/(double)Object.Vertex[i].vcount;
  771.       Object.Vertex[i].zlen=Object.Vertex[i].zlen/(double)Object.Vertex[i].vcount;
  772.     } 
  773.  
  774.     length = 1.0/sqrt(Object.Vertex[i].xlen*Object.Vertex[i].xlen +
  775.                    Object.Vertex[i].ylen*Object.Vertex[i].ylen +
  776.                    Object.Vertex[i].zlen*Object.Vertex[i].zlen );
  777.    
  778.     if (length !=0.0)
  779.     { 
  780.       Object.Vertex[i].Nox = (Object.Vertex[i].xlen * length); 
  781.       Object.Vertex[i].Noy = (Object.Vertex[i].ylen * length); 
  782.       Object.Vertex[i].Noz = (Object.Vertex[i].zlen * length);
  783.     } 
  784.   }
  785.  
  786.  
  787. void InitNormals() 
  788.   register double x1,x2,x3,y1,y2,y3,z1,z2,z3,length;
  789.   register double xlen,ylen,zlen; 
  790.   register int i,j,k; 
  791.  
  792.   /*printf(" first calculate the polygon normals\n"); */
  793.   for(i = Object.NumOfPolygons-1;i>=0 ;i--) 
  794.   { 
  795.     x1=(Object.Vertex[Object.Polygon[i].Vertex[0]].ox); 
  796.     x2=(Object.Vertex[Object.Polygon[i].Vertex[1]].ox); 
  797.     x3=(Object.Vertex[Object.Polygon[i].Vertex[2]].ox); 
  798.     y1=(Object.Vertex[Object.Polygon[i].Vertex[0]].oy); 
  799.     y2=(Object.Vertex[Object.Polygon[i].Vertex[1]].oy); 
  800.     y3=(Object.Vertex[Object.Polygon[i].Vertex[2]].oy); 
  801.     z1=(Object.Vertex[Object.Polygon[i].Vertex[0]].oz); 
  802.     z2=(Object.Vertex[Object.Polygon[i].Vertex[1]].oz); 
  803.     z3=(Object.Vertex[Object.Polygon[i].Vertex[2]].oz); 
  804.    
  805.     /* calculate perpendicular via the cross product of 1st vertex & normal*/ 
  806.     xlen = (y1-y2)*(z1-z3) - (z1-z2)*(y1-y3); 
  807.     ylen = (z1-z2)*(x1-x3) - (x1-x2)*(z1-z3); 
  808.     zlen = (x1-x2)*(y1-y3) - (y1-y2)*(x1-x3); 
  809.     
  810.     /* calculate the length of the normal*/ 
  811.     length = 1.0/sqrt(xlen*xlen + ylen*ylen + zlen*zlen); 
  812.  
  813.     /* scale it to a unit normal*/ 
  814.     if (length!=0.0) 
  815.     { 
  816.       Object.Polygon[i].Nox = (xlen * length); 
  817.       Object.Polygon[i].Noy = (ylen * length); 
  818.       Object.Polygon[i].Noz = (zlen * length); 
  819.     } 
  820.   } 
  821.  
  822.  
  823.   /*This will calculate the normals of the vertices for environment mapping*/ 
  824.   for(i= Object.NumOfVertices-1;i>=0; i--) 
  825.   { 
  826.     Object.Vertex[i].xlen = 0.0;
  827.     Object.Vertex[i].ylen = 0.0;
  828.     Object.Vertex[i].zlen = 0.0;
  829.     Object.Vertex[i].vcount = 0;
  830.   }
  831.  
  832.    
  833.   for(j = Object.NumOfPolygons-1;j>=0 ;j--) 
  834.   { 
  835.     for(k=Object.Polygon[j].NumOfVertices-1;k>=0;k--) 
  836.     { 
  837.         Object.Vertex[Object.Polygon[j].Vertex[k]].xlen += Object.Polygon[j].Nox;
  838.         Object.Vertex[Object.Polygon[j].Vertex[k]].ylen += Object.Polygon[j].Noy;
  839.         Object.Vertex[Object.Polygon[j].Vertex[k]].zlen += Object.Polygon[j].Noz;
  840.         Object.Vertex[Object.Polygon[j].Vertex[k]].vcount ++;
  841.     } 
  842.   } 
  843.    
  844.   for(i= Object.NumOfVertices-1;i>=0; i--) 
  845.   { 
  846.     if(Object.Vertex[i].vcount >0) 
  847.     { 
  848.       Object.Vertex[i].xlen=Object.Vertex[i].xlen/(double)Object.Vertex[i].vcount;
  849.       Object.Vertex[i].ylen=Object.Vertex[i].ylen/(double)Object.Vertex[i].vcount;
  850.       Object.Vertex[i].zlen=Object.Vertex[i].zlen/(double)Object.Vertex[i].vcount;
  851.     } 
  852.  
  853.     length = 1.0/sqrt(Object.Vertex[i].xlen*Object.Vertex[i].xlen +
  854.                    Object.Vertex[i].ylen*Object.Vertex[i].ylen +
  855.                    Object.Vertex[i].zlen*Object.Vertex[i].zlen );
  856.    
  857.     if (length !=0.0)
  858.     { 
  859.       Object.Vertex[i].SNox = (Object.Vertex[i].xlen * length); 
  860.       Object.Vertex[i].SNoy = (Object.Vertex[i].ylen * length); 
  861.       Object.Vertex[i].SNoz = (Object.Vertex[i].zlen * length);
  862.     } 
  863.   }
  864.  
  865.  
  866.  
  867.  
  868.  
  869. void RotateNormals() 
  870.   int i; 
  871.   double nx,ny,nz,cosxangle,sinxangle,cosyangle, 
  872.              sinyangle,coszangle,sinzangle; 
  873.   VertexTYPE *vert; /* pointer to a vertex structure*/ 
  874.  
  875.   /* get sine and cosine angles to save time from table lookup in inner loop*/ 
  876.   sinxangle=sine[xangle]; 
  877.   cosxangle=cosine[xangle]; 
  878.   sinyangle=sine[yangle]; 
  879.   cosyangle=cosine[yangle]; 
  880.   sinzangle=sine[zangle]; 
  881.   coszangle=cosine[zangle]; 
  882.  
  883.   for(i=0;i<Object.NumOfVertices;i++) 
  884.   { 
  885.     vert=&Object.Vertex[i]; 
  886.  
  887.   /* rotate around the x-axis */ 
  888.   vert->Nwz=(vert->Noy * cosxangle) - (vert->Noz * sinxangle); 
  889.   vert->Nwy=(vert->Noy * sinxangle) + (vert->Noz * cosxangle); 
  890.   vert->Nwx=vert->Nox; 
  891.  
  892.   /* rotate around the y-axis */ 
  893.   vert->Nwx = (vert->Nwx * cosyangle) - (vert->Nwz * sinyangle); 
  894.   nz = (vert->Nwx * sinyangle) + (vert->Nwz * cosyangle); 
  895.   vert->Nwz=nz; 
  896.  
  897.   /* rotate around the z-axis */ 
  898.   nx=(vert->Nwx * coszangle) - (vert->Nwy * sinzangle); 
  899.   ny=(vert->Nwx * sinzangle) + (vert->Nwy * coszangle); 
  900.  
  901.   /* reverse the direction of the normals for lightsource shading*/ 
  902.   vert->Nwx=nx; vert->Nwy=ny; vert->Nwz=nz; 
  903.   } 
  904.  
  905. /*-------------------------- calculate color of vertex normal ----------*/ 
  906.  
  907.  
  908.  
  909. void DrawGouraudPolygon(PolygonTYPE *poly)
  910. {
  911.         /*Plot a triangle!*/
  912.     printf("?\n");
  913.         if (poly->NumOfVertices ==3 /*&&  CHROME MASK mode != MASK*/)
  914.         {
  915.           plot_tri_3dfx(poly);
  916.         }
  917.         else
  918.         {
  919.           plot_poly_3dfx(poly);
  920.         }
  921. }
  922.  
  923.  
  924. void MakePolygonList()
  925. {
  926.     int i,j;
  927.  
  928.     VertexTYPE *v0,*v1,*v2;
  929.  
  930.     j=0;
  931.     for(i=0;i<Object.NumOfPolygons;i++)
  932.     {
  933.         v0=&Object.Vertex[Object.Polygon[i].Vertex[0]];
  934.         v1=&Object.Vertex[Object.Polygon[i].Vertex[1]];
  935.         v2=&Object.Vertex[Object.Polygon[i].Vertex[2]];
  936.  
  937.         /* if expression results in a negative then polygon is visible
  938.         if( ((v1->sx - v0->sx) * (v2->sy - v0->sy) - (v1->sy - v0->sy) * (v2->sx - v0->sx)) < 0 )
  939.         {
  940.             PolygonOrderList[j++]=i;
  941.         }*/
  942.     PolygonOrderList[j++]=i; /* all polys visible */
  943.     }
  944.     NumOfSortedPolygons=j;
  945. }
  946.  
  947.  
  948.  
  949. void CalculateColor() 
  950.   int i; 
  951.   int color; 
  952.   double DotProduct,t1,t2; 
  953.  
  954.   for(i=0; i < Object.NumOfVertices; i++) 
  955.   { 
  956.     DotProduct= Object.Vertex[i].Nwx * LightSource.x; 
  957.     t1=   Object.Vertex[i].Nwy * LightSource.y; 
  958.     t2=   Object.Vertex[i].Nwz * LightSource.z; 
  959.     DotProduct += (t1 + t2); 
  960.     t1=DotProduct * 64.0 ; 
  961.     Object.Vertex[i].color = 80.0 + t1; 
  962.   } 
  963.  
  964.  
  965. void RotatePoints() 
  966.   int i; 
  967.   double nx,ny,nz,cosxangle,sinxangle, 
  968.          cosyangle,sinyangle,coszangle,sinzangle; 
  969.   double t1, t2, t3; 
  970.  
  971.  
  972.   /* get the sine and cosine angles to save time from table lookup*/ 
  973.   sinxangle=sine[xangle]; /* Pitch */ 
  974.   cosxangle=cosine[xangle]; 
  975.   sinyangle=sine[yangle];  /* Yaw */ 
  976.   cosyangle=cosine[yangle]; 
  977.   sinzangle=sine[zangle];  /* Roll */ 
  978.   coszangle=cosine[zangle]; 
  979.  
  980.   /* loop through all vertices in object*/ 
  981.   for(i=0;i<Object.NumOfVertices;i++) 
  982.   { 
  983.     /* make a pointer to the current vertex*/ 
  984.     VertexTYPE *vert=&Object.Vertex[i]; 
  985.  
  986.     /* rotate around the x-axis*/ 
  987.  
  988.   vert->wz= ((vert->oy-cy)*cosxangle)-((vert->oz-cz)*sinxangle); 
  989.   vert->wy= ((vert->oy-cy)*sinxangle)+((vert->oz-cz)*cosxangle); 
  990.   vert->wx=vert->ox-cx; 
  991.   /*comment out above line and stick this one in to
  992.   see just how good env. mapping can be :) 
  993.   vert->wx=0.0-cx; */
  994.  
  995.   /* rotate around the y-axis */ 
  996.   nx = (vert->wx*cosyangle)-(vert->wz*sinyangle); 
  997.   nz = (vert->wx*sinyangle)+(vert->wz*cosyangle); 
  998.   vert->wx=nx; 
  999.   vert->wz=nz; 
  1000.  
  1001.   /* rotate around the z-axis*/ 
  1002.   nx = (vert->wx*coszangle)-(vert->wy*sinzangle); 
  1003.   ny = (vert->wx*sinzangle)+(vert->wy*coszangle); 
  1004.   vert->wx=nx; 
  1005.   vert->wy=ny; 
  1006.  
  1007.   /* project the 3-D coordinates to screen coordinates*/ 
  1008.  
  1009.  
  1010.   t3 = vert->wz+zpos;  
  1011.  
  1012.   if (t3<0.00 ) 
  1013.   { 
  1014.     vert->sx =(int)(((vert->wx+xpos)/t3)* /*256.0*/ 512.0)+320;
  1015.     vert->sy =220-(int)(((vert->wy+ypos)/t3)* /*256.0*/ 512.0); 
  1016.   } 
  1017.   else  
  1018.   { /* ooh negative z!*/ 
  1019.     t3 = -1.0; 
  1020.     t3 = -0.1; 
  1021.     t3 = 1.0+ t3;
  1022.     vert->sx =(int)(((vert->wx+xpos)*t3)*512.0)+320; 
  1023.     vert->sy =(int)(((vert->wy+ypos)*t3)*512.0)+220; 
  1024.   } 
  1025.   vert->sz=(int)(vert->wz+zpos); 
  1026.   vert->sz=(int)t3;
  1027.   
  1028.   } 
  1029.  
  1030. /*--------------------------------------------------------------------------*/
  1031.  
  1032.  
  1033.  
  1034. /*--------------------------------------------------------------------*/ 
  1035.  
  1036. void DrawObject()
  1037. {
  1038.     int i;
  1039.  
  1040.     fprintf(fp,"make poly list\n");
  1041.     MakeCulledPolygonList();
  1042.     fprintf(fp,"sort poly list\n");
  1043.     SortPolygonList();
  1044.     fprintf(fp,"calc colour\n");
  1045.     CalculateColor();
  1046. /**/
  1047.     guAlphaSource( GR_ALPHASOURCE_ITERATED_ALPHA );
  1048.     grAlphaBlendFunction( GR_BLEND_SRC_ALPHA, 
  1049.                           GR_BLEND_ONE_MINUS_SRC_ALPHA, 
  1050.                           GR_BLEND_ONE, 
  1051.                           GR_BLEND_ZERO );
  1052.     grAlphaTestFunction( GR_CMP_ALWAYS );
  1053.  
  1054.     guColorCombineFunction(GR_COLORCOMBINE_DECAL_TEXTURE);
  1055.     if (mode == MASK ) /* Turn face on here */
  1056.       guTexSource( facetexture );
  1057.     else
  1058.       guTexSource( *fgtexture );
  1059.     grTexCombineFunction(GR_TMU0, GR_TEXTURECOMBINE_DECAL);
  1060.     /**/
  1061.  
  1062.     for(i=0;i<NumOfSortedPolygons;i++)
  1063.     {
  1064.       if (mode != CMASK)
  1065.         plot_tri_3dfx(&Object.Polygon[PolygonOrderList[i]]);
  1066.       else
  1067.         plot_poly_3dfx(&Object.Polygon[PolygonOrderList[i]]);
  1068.     }
  1069.     
  1070. }
  1071.  
  1072. int
  1073. swapbuffer()
  1074. {
  1075.     while(grBufferNumPending());
  1076.      grBufferSwap(0);
  1077.     
  1078.      guColorCombineFunction( GR_COLORCOMBINE_ITRGB );
  1079.     /* Thi renders a background image */
  1080.     plot_bg();/**/
  1081.  
  1082.      /* Or use this to simply clear the screen - twice as fast o/
  1083.     grBufferClear( 0xFF223344, 0, GR_WDEPTHVALUE_FARTHEST );/**/
  1084. }
  1085.  
  1086.  
  1087.  
  1088.  
  1089. void
  1090. Random ()
  1091. {
  1092. int i,j;
  1093. int pindex;
  1094. int z;
  1095. double xf,yf,zf;
  1096.  
  1097.   Object.NumOfVertices = 0;
  1098.   for (i=0;i<MAXVERTICES;i++)
  1099.   {
  1100.     Object.Vertex[i].ox = 99999;
  1101.   }
  1102.  
  1103.   Object.NumOfVertices=0;
  1104.   for (i=0;i<WATER;i++)
  1105.   {
  1106.     for (j=0;j<WATER;j++)
  1107.     {
  1108.         z = 0;
  1109.         Object.Vertex[i+j*WATER].oy=(double)(i*2.5);
  1110.         Object.Vertex[i+j*WATER].oz=(double)(j*2.5);
  1111.         Object.Vertex[i+j*WATER].ox=(double)(z);
  1112.         Object.Vertex[i+j*WATER].s = (255.0/(double)WATER)*(double)j;
  1113.         Object.Vertex[i+j*WATER].t = (255.0/(double)WATER)*(double)i;
  1114.         Object.NumOfVertices++;
  1115.     }
  1116.  }
  1117.  
  1118.   printf("Object.NumOfVertices=%d\n",Object.NumOfVertices);
  1119.  
  1120.   pindex=0;
  1121.   for (i=1;i<WATER;i++)
  1122.   {
  1123.     for (j=1;j<WATER;j++)
  1124.     { /* Try is clockwise...*/
  1125.       Object.Polygon[pindex].Vertex[0] = (j-1)+(i-1)*WATER;
  1126.       Object.Polygon[pindex].Vertex[2] = (j)+(i)*WATER;
  1127.       Object.Polygon[pindex].Vertex[1] = (j)+(i-1)*WATER;
  1128.       Object.Polygon[pindex].Vertex[3] = 99999;
  1129.       Object.Polygon[pindex].NumOfVertices = 3;
  1130.       pindex++;
  1131.  
  1132.       Object.Polygon[pindex].Vertex[0] = (j-1)+(i-1)*WATER;
  1133.       Object.Polygon[pindex].Vertex[2] = (j-1)+(i)*WATER;
  1134.       Object.Polygon[pindex].Vertex[1] = (j)+(i)*WATER;
  1135.       Object.Polygon[pindex].Vertex[3] = 99999;
  1136.       Object.Polygon[pindex].NumOfVertices = 3;
  1137.       pindex++;
  1138.     }
  1139.   }
  1140.   Object.NumOfPolygons=pindex;
  1141.   printf("Object.NumOfPolygons=%d\n",Object.NumOfPolygons);
  1142.  
  1143.   xf=0.0;yf=0.0;zf=0.0;
  1144.   for (i=0;i<MAXVERTICES;i++)
  1145.   {
  1146.     if (Object.Vertex[i].ox==99999) break;
  1147.     xf = xf + (double) Object.Vertex[i].ox;
  1148.     yf = yf + (double) Object.Vertex[i].oy;
  1149.     zf = zf + (double) Object.Vertex[i].oz;
  1150.   }
  1151.   xf = xf / (double)i; yf = yf / (double)i; zf = zf / (double)i;
  1152.   printf("Average = %f %f %f\n",xf,yf,zf);
  1153.   for (i=0;i<MAXVERTICES;i++)
  1154.   {
  1155.     if (Object.Vertex[i].ox==99999) break;
  1156.     Object.Vertex[i].ox = Object.Vertex[i].ox - (int)xf;
  1157.     Object.Vertex[i].oy = Object.Vertex[i].oy - (int)yf;
  1158.     Object.Vertex[i].oz = Object.Vertex[i].oz - (int)zf;
  1159.   }
  1160.  
  1161. }
  1162.  
  1163. /*----------------------------------------------------------*/
  1164.  
  1165. /*----------------------------------------------------------*/ 
  1166.  
  1167. void ClearVertexList() 
  1168.  
  1169. int i; 
  1170.  
  1171.   Object.NumOfVertices = 0; 
  1172.   for (i=0;i<MAXVERTICES;i++) 
  1173.   { 
  1174.     Object.Vertex[i].ox = 99999; 
  1175.   } 
  1176.  
  1177.  
  1178. /*---------------------- draw gouraud polygon ------------------------------*/ 
  1179.  
  1180.  int
  1181. Load3dfxTexture(char *texfile, GrMipMapId_t *texture)
  1182. {
  1183.  
  1184. Gu3dfInfo         info;
  1185.  
  1186. /* Load Texture */
  1187.   if ( !gu3dfGetInfo( texfile, &info ) )  
  1188.   {
  1189.     fprintf(stderr, "ERROR: could not load %s\n",texfile);
  1190.     grGlideShutdown();
  1191.     exit( -1 );
  1192.   }
  1193.   else
  1194.   {
  1195.      info.data = malloc( info.mem_required );
  1196.  
  1197.      if ( info.data == 0 ) {
  1198.         fprintf( stderr, "out of memory for texture\n" );
  1199.         grGlideShutdown();
  1200.         exit( -1 );
  1201.      }
  1202.  
  1203.      if ( !gu3dfLoad(texfile, &info ) ) {
  1204.         fprintf( stderr, "could not load texture file\n" );
  1205.         grGlideShutdown();
  1206.         exit( -1 );
  1207.      }
  1208.  
  1209.      *texture = guTexAllocateMemory( 0, GR_MIPMAPLEVELMASK_BOTH,
  1210.                                   info.header.width, info.header.height,
  1211.                                   info.header.format,
  1212.                                   GR_MIPMAP_NEAREST,
  1213.                                   info.header.small_lod, info.header.large_lod,
  1214.                                   info.header.aspect_ratio,
  1215.                                   GR_TEXTURECLAMP_WRAP, GR_TEXTURECLAMP_WRAP,
  1216.                                   GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR,
  1217.                                   0.0F,
  1218.                                   FXFALSE );
  1219.      if ( *texture == GR_NULL_MIPMAP_HANDLE ) {
  1220.         fprintf( stderr, "could not allocate memory for lava.3df\n" );
  1221.         grGlideShutdown();
  1222.         exit( -1 );
  1223.      }
  1224.      guTexDownloadMipMap(*texture, info.data, &info.table.nccTable );
  1225.      free( info.data );
  1226.   }
  1227.   return(0);
  1228. }
  1229.  
  1230.  
  1231.  
  1232.  
  1233.  
  1234. void bench ()
  1235. {
  1236.      GrVertex vtx1, vtx2, vtx3;
  1237.      int i;
  1238.      clock_t tim;
  1239.  
  1240.       vtx1.x=100.f;      vtx1.y=100.f;
  1241.       vtx2.x=200.f;      vtx2.y=100.f;
  1242.       vtx3.x=150.f;      vtx3.y=150.f;
  1243.       vtx1.r=189.f;      vtx2.r=10.f;      vtx3.r=99.f;
  1244.       vtx1.g=2.f;      vtx2.g=255.f;      vtx3.g=77.f;
  1245.       vtx1.b=5.f;      vtx2.b=222.f;      vtx3.b=199.f;
  1246.       vtx1.a=220.0f;      vtx2.a=220.0f;      vtx3.a=220.0f;
  1247.  
  1248.       tim=clock();
  1249.  
  1250.       for (i=0;i<5000;i++)
  1251.         grDrawTriangle( &vtx1, &vtx2, &vtx3 );
  1252.     
  1253.       tim=clock()-tim;
  1254.       grBufferSwap(0);
  1255.  
  1256.       while(!kbhit());
  1257.  
  1258.       printf("Elapsed = %lf seconds\n",(double)(tim)/CLOCKS_PER_SEC);   
  1259.       printf("%f tris/sec\n",5000.0f/((double)(tim)/CLOCKS_PER_SEC));
  1260. }
  1261.  
  1262.  
  1263.  
  1264. void plot_bg()
  1265. {
  1266.     static int rot  = 0;
  1267.     double tx, ty;
  1268.  
  1269.     GrVertex vlist[4];
  1270.     rot = (rot++) % (MAXDEGREES-1);
  1271.     tx = sine[rot]*128.0;
  1272.     ty = cosine[rot]*128.0;
  1273.  
  1274.     vlist[0].x = 0.f;
  1275.     vlist[0].y = 0.f;
  1276.     vlist[0].r=128.0f;
  1277.     vlist[0].g=0.0f;
  1278.     vlist[0].b=0.0f;
  1279.     vlist[0].a=255.0f;
  1280.  
  1281.     vlist[1].x = 640.f;
  1282.     vlist[1].y = 0.f;
  1283.     vlist[1].r=200.0f;
  1284.     vlist[1].g=0.0f;
  1285.     vlist[1].b=0.0f;
  1286.     vlist[1].a=255.0f;
  1287.  
  1288.     vlist[2].x = 0.f;
  1289.     vlist[2].y = 480.f;
  1290.     vlist[2].r=55.0f;
  1291.     vlist[2].g=0.0f;
  1292.     vlist[2].b=0.0f;
  1293.     vlist[2].a=255.0f;
  1294.  
  1295.     vlist[3].x = 640.f;
  1296.     vlist[3].y = 480.f;
  1297.     vlist[3].r=100.0f;
  1298.     vlist[3].g=0.0f;
  1299.     vlist[3].b=0.0f;
  1300.     vlist[3].a=255.0f;
  1301.  
  1302.     vlist[0].oow=1.f/2000.0f;
  1303.     vlist[1].oow=1.f/2000.0f;
  1304.     vlist[2].oow=1.f/2000.0f;
  1305.     vlist[3].oow=1.f/2000.0f;
  1306.  
  1307.     vlist[0].tmuvtx[0].sow = (tx+128.0)   * vlist[0].oow; 
  1308.     vlist[0].tmuvtx[0].tow = (ty+128.0)   * vlist[0].oow;
  1309.  
  1310.     vlist[1].tmuvtx[0].sow = (128.0-ty)   * vlist[1].oow; 
  1311.     vlist[1].tmuvtx[0].tow = (tx+128.0) * vlist[1].oow;
  1312.  
  1313.     vlist[2].tmuvtx[0].sow = (ty+128.0)   * vlist[2].oow; 
  1314.     vlist[2].tmuvtx[0].tow = (128.0-tx)   * vlist[2].oow;
  1315.  
  1316.     vlist[3].tmuvtx[0].sow = (128.0-tx) * vlist[3].oow; 
  1317.     vlist[3].tmuvtx[0].tow = (128.0-ty) * vlist[3].oow;
  1318.  
  1319.  
  1320.     
  1321.     guColorCombineFunction(GR_COLORCOMBINE_DECAL_TEXTURE);
  1322.     guTexSource( *bgtexture );
  1323.     grTexCombineFunction(GR_TMU0, GR_TEXTURECOMBINE_DECAL);
  1324.  
  1325.     /* hmm do bias bit .. */
  1326.     grDrawTriangle(&vlist[0],&vlist[1],&vlist[2]);
  1327.     grDrawTriangle(&vlist[1],&vlist[3],&vlist[2]);
  1328.     
  1329.     
  1330.     guColorCombineFunction( GR_COLORCOMBINE_ITRGB );
  1331. }
  1332.  
  1333.  
  1334.  
  1335. void plot_poly_3dfx (PolygonTYPE *poly)
  1336. {
  1337.      GrVertex vlist[255];
  1338.      GrState state;
  1339.      int i;
  1340.      float sow[4],tow[4];
  1341.      float s,t;
  1342.  
  1343.      sow[0] = 0.0f;tow[0]=0.0f;
  1344.      sow[1] = 255.0f;tow[1]=0.0f;
  1345.      sow[2] = 255.0f;tow[2]=255.0f;
  1346.      sow[3] = 0.0f;tow[3]=255.0f;
  1347.  
  1348.      for (i=0;i<poly->NumOfVertices;i++)
  1349.      {
  1350.       vlist[i].x=(float)Object.Vertex[poly->Vertex[i]].sx;
  1351.       vlist[i].y=(float)Object.Vertex[poly->Vertex[i]].sy;
  1352.  
  1353.       vlist[i].r=(float)Object.Vertex[poly->Vertex[i]].color;
  1354.       vlist[i].g=(float)Object.Vertex[poly->Vertex[i]].color*0.f;
  1355.       vlist[i].b=(float)Object.Vertex[poly->Vertex[i]].color*0.f;
  1356.  
  1357.       vlist[i].a=255.0f;
  1358.       /*vlist[i].a=(float)Object.Vertex[poly->Vertex[i]].color;*/
  1359.  
  1360.       vlist[i].oow = -1.f/(float)Object.Vertex[poly->Vertex[i]].sz;
  1361.       
  1362.  
  1363.         /*
  1364.       vlist[i].tmuvtx[0].sow = sow[i % 4]   * vlist[i].oow;
  1365.       vlist[i].tmuvtx[0].tow = tow[i % 4]   * vlist[i].oow;
  1366.       */
  1367.       
  1368.       Object.Vertex[poly->Vertex[i]].s = 127.0 +(127.0/20.0) *
  1369.           Object.Vertex[poly->Vertex[i]].wx; /* Adjust height wise */
  1370.  
  1371.       Object.Vertex[poly->Vertex[i]].t = 127.0 +(127.0/20.0) *
  1372.           -Object.Vertex[poly->Vertex[i]].wy; /* Adjust width wise */
  1373.       
  1374.  
  1375.  
  1376.       
  1377.       vlist[i].tmuvtx[0].sow =
  1378.   (Object.Vertex[poly->Vertex[i]].s - 40.0*Object.Vertex[poly->Vertex[i]].Nox)
  1379.                      * vlist[i].oow;
  1380.  
  1381.       vlist[i].tmuvtx[0].tow = 
  1382.   (Object.Vertex[poly->Vertex[i]].t - 40.0*Object.Vertex[poly->Vertex[i]].Noy)
  1383.                      * vlist[i].oow;
  1384. /*
  1385.       vlist[i].tmuvtx[0].sow =
  1386.   (Object.Vertex[poly->Vertex[i]].s + 40.0*
  1387.   (Object.Vertex[poly->Vertex[i]].SNox+Object.Vertex[poly->Vertex[i]].Nox))
  1388.                      * vlist[i].oow;
  1389.  
  1390.       vlist[i].tmuvtx[0].tow = 
  1391.   (Object.Vertex[poly->Vertex[i]].t + 40.0*
  1392.   (Object.Vertex[poly->Vertex[i]].SNoy+Object.Vertex[poly->Vertex[i]].Noy))
  1393.                      * vlist[i].oow;*/
  1394.  
  1395. /*
  1396.       vlist[i].tmuvtx[0].sow = (Object.Vertex[poly->Vertex[i]].s) * vlist[i].oow;
  1397.       vlist[i].tmuvtx[0].tow = (Object.Vertex[poly->Vertex[i]].t) * vlist[i].oow;
  1398. */
  1399.       
  1400.       if (vlist[i].x > 640 ||
  1401.           vlist[i].x <0    ||
  1402.           vlist[i].y >480  ||
  1403.           vlist[i].y <0 ) return;
  1404.       
  1405.      }
  1406. #ifdef GO
  1407.     grDrawPlanarPolygonVertexList(poly->NumOfVertices,vlist);
  1408.     /*guColorCombineFunction( GR_COLORCOMBINE_ITRGB );*/
  1409. #endif
  1410.  
  1411.     /* save state! */
  1412.     grGlideGetState(&state);
  1413.  
  1414.     /* projected textrure :( */
  1415.  
  1416.      for (i=0;i<poly->NumOfVertices;i++)
  1417.      {
  1418.       s = (20.0f * vlist[i].oow)*(vlist[i].x - 320.0f) ;
  1419.       t = (20.0f * vlist[i].oow)*(240.0f - vlist[i].y) ;
  1420.       s = (s+320.0f)/2.5098f;
  1421.       t = (t+240.0f)/1.8824f;
  1422.  
  1423.       vlist[i].tmuvtx[0].sow = s   * vlist[i].oow;
  1424.       vlist[i].tmuvtx[0].tow = t   * vlist[i].oow;
  1425.       vlist[i].tmuvtx[0].oow = 20.0f * vlist[i].oow;
  1426.     }
  1427. #ifdef GO
  1428.     guColorCombineFunction(GR_COLORCOMBINE_DECAL_TEXTURE);
  1429.     grAlphaBlendFunction(GR_BLEND_ONE,GR_BLEND_ONE,
  1430.                          GR_BLEND_ONE,GR_BLEND_ZERO);
  1431.  
  1432.     guTexSource( spotlight);
  1433.     grTexCombineFunction(GR_TMU0, GR_TEXTURECOMBINE_DECAL);
  1434.     grDrawPlanarPolygonVertexList(poly->NumOfVertices,vlist);
  1435.     
  1436. #endif
  1437.     /* restore state */
  1438.     grGlideSetState(&state);
  1439. }
  1440.  
  1441. /*???*/
  1442. void plot_tri_3dfx (PolygonTYPE *poly)
  1443. {
  1444.      GrVertex vtx1, vtx2, vtx3;
  1445.      GrState state ;
  1446.      float s,t;
  1447.      long tmp;
  1448.  
  1449.       vtx1.x=(float)Object.Vertex[poly->Vertex[0]].sx;
  1450.       vtx1.y=(float)Object.Vertex[poly->Vertex[0]].sy;
  1451.  
  1452.       vtx2.x=(float)Object.Vertex[poly->Vertex[1]].sx;
  1453.       vtx2.y=(float)Object.Vertex[poly->Vertex[1]].sy;
  1454.  
  1455.       vtx3.x=(float)Object.Vertex[poly->Vertex[2]].sx;
  1456.       vtx3.y=(float)Object.Vertex[poly->Vertex[2]].sy;
  1457.  
  1458. vtx1.r=(float)Object.Vertex[poly->Vertex[0]].ox*20.0+128.0;
  1459. vtx2.r=(float)Object.Vertex[poly->Vertex[1]].ox*20.0+128.0;
  1460. vtx3.r=(float)Object.Vertex[poly->Vertex[2]].ox*20.0+128.0;
  1461.  
  1462. vtx1.g=(float)Object.Vertex[poly->Vertex[0]].ox*20.0+128.0;
  1463. vtx2.g=(float)Object.Vertex[poly->Vertex[1]].ox*20.0+128.0;
  1464. vtx3.g=(float)Object.Vertex[poly->Vertex[2]].ox*20.0+128.0;
  1465.  
  1466. vtx1.b=(float)Object.Vertex[poly->Vertex[0]].ox*20.0+128.0;
  1467. vtx2.b=(float)Object.Vertex[poly->Vertex[1]].ox*20.0+128.0;
  1468. vtx3.b=(float)Object.Vertex[poly->Vertex[2]].ox*20.0+128.0;
  1469.  
  1470.  
  1471. /*  SNAP */
  1472. tmp = vtx1.x * 16;    // increase by 4 bits, truncate off the rest
  1473. vtx1.x = tmp / 16.0;    // remove extra 4 bits, convert back to float
  1474. tmp = vtx1.y * 16;    // increase by 4 bits, truncate off the rest
  1475. vtx1.y = tmp / 16.0;    // remove extra 4 bits, convert back to float
  1476.  
  1477. tmp = vtx2.x * 16;    // increase by 4 bits, truncate off the rest
  1478. vtx2.x = tmp / 16.0;    // remove extra 4 bits, convert back to float
  1479. tmp = vtx2.y * 16;    // increase by 4 bits, truncate off the rest
  1480. vtx2.y = tmp / 16.0;    // remove extra 4 bits, convert back to float
  1481.  
  1482. tmp = vtx3.x * 16;    // increase by 4 bits, truncate off the rest
  1483. vtx3.x = tmp / 16.0;    // remove extra 4 bits, convert back to float
  1484. tmp = vtx3.y * 16;    // increase by 4 bits, truncate off the rest
  1485. vtx3.y = tmp / 16.0;    // remove extra 4 bits, convert back to float
  1486.  
  1487.  
  1488. /*o/  vtx1.a=220.0f;
  1489.       vtx2.a=220.0f;
  1490.       vtx3.a=220.0f;/**/
  1491.  
  1492. /**/  vtx1.a=255.0f;
  1493.       vtx2.a=255.0f;
  1494.       vtx3.a=255.0f;/**/
  1495.  
  1496.       /* Make the alpha value (transparency) equal to the
  1497.          colour at each vertex - the brighter it is, the
  1498.          less transparent it is. Gives a nice 'glare' effect */
  1499.  
  1500. /*      vtx1.a=(float)Object.Vertex[poly->Vertex[0]].color;
  1501.       vtx2.a=(float)Object.Vertex[poly->Vertex[1]].color;
  1502.       vtx3.a=(float)Object.Vertex[poly->Vertex[2]].color;/**/
  1503.  
  1504.       vtx1.oow = -1.f/(float)Object.Vertex[poly->Vertex[0]].sz;
  1505.       vtx2.oow = -1.f/(float)Object.Vertex[poly->Vertex[1]].sz;
  1506.       vtx3.oow = -1.f/(float)Object.Vertex[poly->Vertex[2]].sz;
  1507.  
  1508.  
  1509.       
  1510. /*if (vtx1.x<-50.0|| vtx1.y <-50.0 || 
  1511.     vtx1.x >690.0 || vtx1.y >520.0||
  1512.   vtx2.x <-50.0 || vtx2.y <-50.0 ||
  1513.   vtx2.x >690.0 || vtx2.y >530.0||
  1514.   vtx3.x <-50.0 || vtx3.y <-50.0 || 
  1515.   vtx3.x >690.0 || vtx3.y >530.0||*/
  1516. /*
  1517.  if ( vtx1.oow <0.0 || vtx2.oow <0.0 || vtx3.oow <0.0)
  1518.         return;*/
  1519.         
  1520.       /*if (vtx1.oow <0.0 || vtx2.oow <0.0 || vtx3.oow <0.0)
  1521.           return;*/
  1522.  
  1523.       if (vtx1.oow <0.0) vtx1.oow = 0.9999;
  1524.       if (vtx2.oow <0.0) vtx2.oow = 0.9999;
  1525.       if (vtx3.oow <0.0) vtx3.oow = 0.9999;/**/
  1526.     
  1527.       /**/
  1528.       if (vtx1.x<1.0) vtx1.x = 1.0;
  1529.       if (vtx1.x>640.0) vtx1.x = 640.0;
  1530.       if (vtx1.y<1.0) vtx1.y =  1.0;
  1531.       if (vtx1.y>480.0) vtx1.y = 480.0;
  1532.  
  1533.       if (vtx2.x<1.0) vtx2.x = 1.0;
  1534.       if (vtx2.x>640.0) vtx2.x = 640.0;
  1535.       if (vtx2.y<1.0) vtx2.y = 1.0;
  1536.       if (vtx2.y>480.0) vtx2.y = 480.0;
  1537.  
  1538.       if (vtx3.x<1.0) vtx3.x =  1.0;
  1539.       if (vtx3.x>640.0) vtx3.x = 640.0;
  1540.       if (vtx3.y<1.0) vtx3.y = 1.0;
  1541.       if (vtx3.y>480.0) vtx3.y = 480.0;/**/
  1542. /*
  1543.       vtx1.tmuvtx[0].sow = 0.f   * vtx1.oow;
  1544.       vtx1.tmuvtx[0].tow = 0.f   * vtx1.oow;
  1545.       vtx2.tmuvtx[0].sow = 255.f * vtx2.oow;
  1546.       vtx2.tmuvtx[0].tow = 255.f * vtx2.oow;
  1547.       vtx3.tmuvtx[0].sow = 255.f * vtx3.oow;
  1548.       vtx3.tmuvtx[0].tow = 0.f   * vtx3.oow;
  1549. */
  1550.  
  1551. if (mode == SURFACE)
  1552. {
  1553. vtx1.tmuvtx[0].sow =
  1554.  (Object.Vertex[poly->Vertex[0]].s + 100.0*Object.Vertex[poly->Vertex[0]].Noz)
  1555.                      * vtx1.oow;
  1556. vtx1.tmuvtx[0].tow = 
  1557.   (Object.Vertex[poly->Vertex[0]].t + 100.0*Object.Vertex[poly->Vertex[0]].Noy)
  1558.                      * vtx1.oow;
  1559. vtx2.tmuvtx[0].sow =
  1560.   (Object.Vertex[poly->Vertex[1]].s + 100.0*Object.Vertex[poly->Vertex[1]].Noz)
  1561.                      * vtx2.oow;
  1562. vtx2.tmuvtx[0].tow = 
  1563.   (Object.Vertex[poly->Vertex[1]].t + 100.0*Object.Vertex[poly->Vertex[1]].Noy)
  1564.                      * vtx2.oow;
  1565. vtx3.tmuvtx[0].sow = 
  1566.   (Object.Vertex[poly->Vertex[2]].s + 100.0*Object.Vertex[poly->Vertex[2]].Noz)
  1567.                       * vtx3.oow;
  1568. vtx3.tmuvtx[0].tow = 
  1569.   (Object.Vertex[poly->Vertex[2]].t + 100.0*Object.Vertex[poly->Vertex[2]].Noy)
  1570.                      * vtx3.oow;
  1571. }
  1572. else if (mode == BLOB)/* BLOB */
  1573. {
  1574. vtx1.tmuvtx[0].sow =
  1575.   (Object.Vertex[poly->Vertex[0]].s + 100.00*
  1576.   (Object.Vertex[poly->Vertex[0]].SNox-Object.Vertex[poly->Vertex[0]].Nox))
  1577.                      * vtx1.oow;
  1578. vtx1.tmuvtx[0].tow = 
  1579.   (Object.Vertex[poly->Vertex[0]].t + 100.0*
  1580.   (Object.Vertex[poly->Vertex[0]].SNoy-Object.Vertex[poly->Vertex[0]].Noy))
  1581.                      * vtx1.oow;
  1582. vtx2.tmuvtx[0].sow =
  1583.   (Object.Vertex[poly->Vertex[1]].s + 100.0*
  1584.   (Object.Vertex[poly->Vertex[1]].SNox-Object.Vertex[poly->Vertex[1]].Nox))
  1585.                      * vtx2.oow;
  1586. vtx2.tmuvtx[0].tow = 
  1587.   (Object.Vertex[poly->Vertex[1]].t + 100.0*
  1588.   (Object.Vertex[poly->Vertex[1]].SNoy-Object.Vertex[poly->Vertex[1]].Noy))
  1589.                      * vtx2.oow;
  1590. vtx3.tmuvtx[0].sow = 
  1591.   (Object.Vertex[poly->Vertex[2]].s + 100.0*
  1592.   (Object.Vertex[poly->Vertex[2]].SNox-Object.Vertex[poly->Vertex[2]].Nox))
  1593.                       * vtx3.oow;
  1594. vtx3.tmuvtx[0].tow = 
  1595.   (Object.Vertex[poly->Vertex[2]].t + 100.0*
  1596.   (Object.Vertex[poly->Vertex[2]].SNoy-Object.Vertex[poly->Vertex[2]].Noy))
  1597.                      * vtx3.oow;
  1598. }
  1599. else
  1600. {
  1601.   vtx1.tmuvtx[0].sow = (Object.Vertex[poly->Vertex[0]].s) * vtx1.oow;
  1602.   vtx1.tmuvtx[0].tow = (Object.Vertex[poly->Vertex[0]].t) * vtx1.oow;
  1603.   vtx2.tmuvtx[0].sow = (Object.Vertex[poly->Vertex[1]].s) * vtx2.oow;
  1604.   vtx2.tmuvtx[0].tow = (Object.Vertex[poly->Vertex[1]].t) * vtx2.oow;
  1605.   vtx3.tmuvtx[0].sow = (Object.Vertex[poly->Vertex[2]].s) * vtx3.oow;
  1606.   vtx3.tmuvtx[0].tow = (Object.Vertex[poly->Vertex[2]].t) * vtx3.oow;
  1607. }
  1608.  
  1609. /*if (Object.Vertex[poly->Vertex[2]].Noy != 0.0)
  1610. printf("nx ny nz %f %f %f\n",
  1611.        Object.Vertex[poly->Vertex[2]].Nox,
  1612.        Object.Vertex[poly->Vertex[2]].Noy,
  1613.        Object.Vertex[poly->Vertex[2]].Noz);*/
  1614. #ifdef GO
  1615.     /*guDrawTriangleWithClip( &vtx1, &vtx2, &vtx3 );*/
  1616.      grDrawTriangle( &vtx1, &vtx2, &vtx3 );
  1617. #endif
  1618.  
  1619. return;
  1620.  
  1621.     /* save state! Very inefficient way of doing this
  1622.        should readly draw all basic texture polys first 
  1623.        and then draw them all using prjected texture
  1624.        mapping. But I don't care :) */
  1625.  
  1626.     grGlideGetState(&state);
  1627.  
  1628.     
  1629.       /* My head hurts :( */
  1630. #ifdef GO
  1631.     guColorCombineFunction(GR_COLORCOMBINE_ITRGB );
  1632.     
  1633.     grAlphaCombine(GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_ONE,
  1634.                    GR_COMBINE_LOCAL_NONE,GR_COMBINE_OTHER_CONSTANT,
  1635.                    FXFALSE);
  1636.  
  1637.  
  1638.     grAlphaBlendFunction(GR_BLEND_ONE,GR_BLEND_ONE,
  1639.                          GR_BLEND_ONE,GR_BLEND_ZERO);
  1640.  
  1641.     grAlphaTestFunction( GR_CMP_ALWAYS );
  1642.     grDrawTriangle( &vtx1, &vtx2, &vtx3 );
  1643. #endif
  1644.     
  1645.     /* restore state */
  1646.     grGlideSetState(&state);
  1647. }
  1648.  
  1649.  
  1650.  
  1651.  
  1652.  
  1653.  
  1654.  
  1655. /*---------------------------------------------------------------*/ 
  1656.  
  1657. int _cdecl main(int argc,char**argv) 
  1658. int x,y; 
  1659. int index=0; 
  1660.  
  1661.   system("del out\n");
  1662.   fp=fopen("listval.txt","w");
  1663.   setbuf(fp,0);
  1664.  
  1665.  
  1666.   build_table();
  1667.   build_itable();
  1668.  
  1669.   /* set up Glide and the hardware  */
  1670.   screenRes = GR_RESOLUTION_640x480;
  1671.   grSstQueryBoards(&hwconfig);
  1672.   fprintf(stdout,"Number of boards = %d\n",hwconfig.num_sst);
  1673.   fflush(stdout);
  1674.  
  1675.   grGlideInit();
  1676.   if ( !grSstQueryHardware( &hwconfig ) )
  1677.   {
  1678.     fprintf( stderr, "main: grSstQueryHardware failed!\n" );
  1679.     grGlideShutdown();
  1680.     exit( -1 );
  1681.   }
  1682.  
  1683.   grSstSelect( 0 );
  1684.   if ( !grSstOpen( screenRes,
  1685.                    GR_REFRESH_75Hz,
  1686.                    GR_COLORFORMAT_ARGB,
  1687.                    GR_ORIGIN_LOWER_LEFT,
  1688.                    GR_SMOOTHING_ENABLE,
  1689.                    2 ) )
  1690.   {
  1691.     fprintf( stderr, "main: grSstOpen failed!\n" );
  1692.     grGlideShutdown();
  1693.     exit( -1 );
  1694.   }
  1695.  
  1696.     printf("Gouraud Shaded Vectors 2\n");
  1697.     strcpy(filename,"diamond.v10");
  1698.  
  1699.     max = 99999;
  1700.  
  1701.     if (argc>1)  max = atoi(argv[1]);
  1702.  
  1703.     printf("max=%d\n",max);
  1704.     
  1705.     guColorCombineFunction( GR_COLORCOMBINE_ITRGB );
  1706.  
  1707.     guAlphaSource( GR_ALPHASOURCE_ITERATED_ALPHA );
  1708.     grAlphaBlendFunction( GR_BLEND_SRC_ALPHA, 
  1709.                           GR_BLEND_ONE_MINUS_SRC_ALPHA, 
  1710.                           GR_BLEND_ONE, 
  1711.                           GR_BLEND_ZERO );
  1712.     grAlphaTestFunction( GR_CMP_ALWAYS );
  1713.  
  1714.     /*bench(); /* noddy benchmark procedure  - ignore 
  1715.     grBufferClear( 0x000000, 0, GR_WDEPTHVALUE_FARTHEST );
  1716.     grBufferSwap(0);
  1717.     grBufferClear( 0x000000, 0, GR_WDEPTHVALUE_FARTHEST );*/
  1718.  
  1719. /* 
  1720.    image0 - dots
  1721.    image1 - 
  1722.    image2 - BW 
  1723.    image3 - 
  1724.    image4 - dunes 
  1725.    image5 moon
  1726.  */
  1727.     /* Texture for CHROME surface */
  1728.     Load3dfxTexture("image0.3df",&texture1);
  1729.     Load3dfxTexture("image1.3df",&texture2);
  1730.     Load3dfxTexture("image2.3df",&texture3);
  1731.     Load3dfxTexture("image3.3df",&texture4);
  1732.     Load3dfxTexture("image4.3df",&texture5);
  1733.     Load3dfxTexture("image5.3df",&texture6);
  1734.     
  1735.     /* point object and background textures at some defaults */
  1736.     fgtexture = &texture4;
  1737.     bgtexture = &texture4;
  1738.  
  1739.     /* Texture for MASK surface */
  1740.     Load3dfxTexture("facehi.3df",&facetexture);
  1741.  
  1742.     Load3dfxTexture("spot.3df",&spotlight);
  1743.  
  1744.     Demo();
  1745.     grGlideShutdown();
  1746.     return(0);
  1747. }
  1748.  
  1749.  
  1750. void
  1751. ChangeTextures ()
  1752. {
  1753.     switch(rand()%6)
  1754.     {
  1755.     case 0:
  1756.         fgtexture = &texture1;
  1757.         break;
  1758.     case 1:
  1759.         fgtexture = &texture2;
  1760.         break;
  1761.     case 2:
  1762.         fgtexture = &texture3;
  1763.         break;
  1764.     case 3:
  1765.         fgtexture = &texture4;
  1766.         break;
  1767.      case 4:
  1768.          fgtexture = &texture5;
  1769.         break;
  1770.     case 5:
  1771.         fgtexture = &texture6;
  1772.         break;
  1773.     default:;
  1774.     }
  1775.  
  1776.   bgtexture = fgtexture;
  1777.  
  1778. }
  1779.     
  1780.  
  1781.  
  1782.  
  1783. void Demo(void) 
  1784.   int i; 
  1785.   int frames = 0;
  1786.   int count=0; 
  1787.   int next;
  1788.   long int tim; 
  1789.   double vel = 4.0; 
  1790.   int level = 1;
  1791.   
  1792.   mode = SURFACE ;
  1793.   
  1794.   ClearVertexList(); 
  1795.   Random();
  1796.  
  1797.   srand( (unsigned)time( NULL ) );
  1798.  
  1799.   init();
  1800.  
  1801.   printf("init norms\n"); 
  1802.   
  1803.   InitNormals();
  1804.   FInitNormals(); 
  1805.  
  1806.   /* initialize a few things*/ 
  1807.   printf("initialize a few things\n"); 
  1808.   InitYTable(); 
  1809.   InitTrigTables(); 
  1810.   InitLightSource(); 
  1811.  
  1812.   /* initialize angle and position of object*/ 
  1813.   xangle=0; yangle=80/*64*/; zangle=256; 
  1814.   zpos=-1024.0; 
  1815.   zpos=-512.0; 
  1816.   zpos=-10.25; 
  1817.  
  1818.   cx = 31 ; cy = 20; cz = 0; 
  1819.  
  1820.   /* draw first frame so that globe won't "pop out of nowhere" (:*/ 
  1821.   MakeViewPolygonList(); 
  1822.  
  1823.   RotatePoints(); 
  1824.   RotateNormals(); 
  1825.   DrawObject(); 
  1826.  
  1827.   tim=clock(); 
  1828.   next = 200;
  1829.   /*mode = CMASK;DoFace();yangle=0;cx=0;*/
  1830.   /*if (rand()%2) mode = MASK;*/
  1831.   /*mode = BLOB; DoSphere(5);*/
  1832.   do 
  1833.   { 
  1834.       if (mode == SURFACE || mode == BLOB)
  1835.          calcFc (mode); 
  1836.  
  1837.       MakeViewPolygonList();
  1838.       
  1839.       RotatePoints();
  1840.       
  1841.       FInitNormals();
  1842.      
  1843.       if (mode == MASK)
  1844.           RotateNormals; /* copy out for chrome face */
  1845.     
  1846.       DrawObject();
  1847.       swapbuffer();
  1848.  
  1849.       xangle++; xangle = xangle % MAXDEGREES; 
  1850.       cy = cosine[(MAXDEGREES-xangle)%MAXDEGREES] * 60;
  1851.       cz =   sine[(MAXDEGREES-xangle)%MAXDEGREES] * 60;
  1852.       frames++;
  1853.  
  1854. /**/
  1855.       if (frames % (mode==CMASK?800:1200)==0) 
  1856.       {
  1857.         init ();
  1858.         if (mode == SURFACE)
  1859.         {
  1860.           ChangeTextures();
  1861.           mode = BLOB;
  1862.           DoSphere(4+rand()%1);
  1863.         }
  1864.         else if (mode == BLOB)
  1865.         { 
  1866.           ChangeTextures();
  1867.           yangle=0;cx=0;
  1868.              DoFace();
  1869.           mode = CMASK;
  1870.           if (rand()%8 == 0) mode = MASK;
  1871.         }
  1872.         else
  1873.         {
  1874.           ChangeTextures();
  1875.           yangle=80;cx=31;
  1876.           mode = SURFACE;
  1877.           Random();
  1878.         }
  1879.       }
  1880. /**/
  1881.  
  1882.       if (frames % next == 0)
  1883.       {
  1884.         V[rand()%WATER][rand()%WATER] = rand()%7+8;
  1885.         next = rand()%14;
  1886.         next = next*next+100;
  1887.  
  1888.         Vb[rand()%Object.NumOfVertices] = rand()%7;
  1889.       }
  1890.   } while(frames < max && !kbhit()); 
  1891.  
  1892.   tim=clock()-tim; 
  1893.   printf("Elapsed = %lf seconds\n",(double)(tim)/CLOCKS_PER_SEC);
  1894.   printf("FPS     = %lf \n",(double)frames/
  1895.                             ((double)(tim)/CLOCKS_PER_SEC));
  1896.  
  1897. int
  1898. sleep(int x)
  1899. {
  1900.     long int tim;
  1901.     tim = clock();
  1902.  
  1903.     while (clock() < tim+x) ;
  1904.     return(0);
  1905. }
  1906.  
  1907.  
  1908. void MakeCulledPolygonList() 
  1909.   int i,j; 
  1910.  
  1911.   VertexTYPE *v0,*v1,*v2; 
  1912.  
  1913.   j=0; 
  1914.   for(i=0;i<NumOfViewedPolygons;i++) 
  1915.   { 
  1916.     v0=&Object.Vertex[Object.Polygon[PolygonViewList[i]].Vertex[0]]; 
  1917.     v1=&Object.Vertex[Object.Polygon[PolygonViewList[i]].Vertex[1]]; 
  1918.     v2=&Object.Vertex[Object.Polygon[PolygonViewList[i]].Vertex[2]]; 
  1919.  
  1920.     /* if expression results in a negative then polygon is visible*/ 
  1921.     if( ((v1->sx-v0->sx) * (v2->sy-v0->sy) - (v1->sy - v0->sy)  
  1922.         *(v2->sx-v0->sx)) > 0 || mode == MASK || mode == CMASK) 
  1923.     { 
  1924.       PolygonOrderList[j++]  =PolygonViewList[i]; 
  1925.     } 
  1926.   } 
  1927.   NumOfSortedPolygons=j; 
  1928.  
  1929.  
  1930.  
  1931. void SortPolygonList() 
  1932.   int i,j; 
  1933.   int maxz,minz; 
  1934.   PolygonTYPE *poly; 
  1935.  
  1936.   /* first find the distance of each polygon (from midpoint of max & min z's)*/ 
  1937.   for(i=0;i<Object.NumOfPolygons;i++) 
  1938.   { 
  1939.  
  1940.     poly=&Object.Polygon[i]; 
  1941.     minz=65535; 
  1942.     maxz=-65536; 
  1943.     for(j=0;j<poly->NumOfVertices;j++) 
  1944.     { 
  1945.       if(Object.Vertex[poly->Vertex[j]].sz < minz) 
  1946.       { 
  1947.         minz=Object.Vertex[poly->Vertex[j]].sz; 
  1948.       } 
  1949.       if(Object.Vertex[poly->Vertex[j]].sz > maxz) 
  1950.       { 
  1951.         maxz=Object.Vertex[poly->Vertex[j]].sz; 
  1952.       } 
  1953.     } 
  1954.     /* now calculate the distance*/ 
  1955.     poly->zcenter=(maxz+minz)<<1; 
  1956.   } 
  1957.  
  1958.   /* qsort the polygons*/ 
  1959.   qsort(PolygonOrderList,NumOfSortedPolygons,sizeof(int),ComparePolygons); 
  1960.   /* all done the sorting process*/ 
  1961.  
  1962.  
  1963. int _cdecl ComparePolygons(const void *a, const void *b) 
  1964.   if( Object.Polygon[*(int *)a].zcenter < Object.Polygon[*(int *)b].zcenter ) 
  1965.   { 
  1966.     return -1; 
  1967.   } 
  1968.   else if( Object.Polygon[*(int *)a].zcenter >  
  1969.            Object.Polygon[*(int *)b].zcenter ) 
  1970.   { 
  1971.     return +1; 
  1972.   } 
  1973.   else 
  1974.   { 
  1975.     return 0; 
  1976.   } 
  1977.  
  1978. /*-------------------------- inilialize light source -----------------------*/ 
  1979.  
  1980. void InitLightSource(void) 
  1981.   double xlen,ylen,zlen,length; 
  1982.  
  1983.   /* assign the delault light source position*/ 
  1984.   xlen=-10; ylen=-10; zlen=-10; 
  1985.  
  1986.   /* calculate the length of the vector (light source to 0,0,0)*/ 
  1987.   length = sqrt(xlen*xlen + ylen*ylen + zlen*zlen); 
  1988.  
  1989.   /* scale it to a unit vector*/ 
  1990.   LightSource.x = (xlen/length); 
  1991.   LightSource.y = (ylen/length); 
  1992.   LightSource.z = (zlen/length); 
  1993.  
  1994. /*==========================================================*/ 
  1995.   
  1996.  
  1997.  
  1998.  
  1999. int 
  2000. Visible(double tx, double ty) 
  2001.   if (lsign*(axl*tx-byl*ty-cl) > 0.0  && 
  2002.       rsign*(axr*tx-byr*ty-cr) < 0.0) 
  2003.     return(1); 
  2004.   else 
  2005.     return(0); 
  2006.  
  2007.  
  2008.  
  2009. int qabs(int x) 
  2010. int copy  = x >>31; 
  2011. x ^= copy; 
  2012. return x-copy; 
  2013.  
  2014.  
  2015.  
  2016.  
  2017. void MakeViewPolygonList()
  2018. {
  2019.   int i,j;
  2020.   VertexTYPE *v0,*v1,*v2;
  2021.  
  2022.   theta = (256+512+xangle)%MAXDEGREES;
  2023.   CalcViewTriangle(cz,cy,theta);
  2024.  
  2025.   j=0; 
  2026.   for(i=0;i<Object.NumOfPolygons;i++)
  2027.   {
  2028.     v0=&Object.Vertex[Object.Polygon[i].Vertex[0]];
  2029.     v1=&Object.Vertex[Object.Polygon[i].Vertex[1]];
  2030.     v2=&Object.Vertex[Object.Polygon[i].Vertex[2]];
  2031.  
  2032.     if ((lsign*(axl*v1->oz-byl*v1->oy-cl) > 0.0  &&
  2033.          rsign*(axr*v1->oz-byr*v1->oy-cr) < 0.0) ||
  2034.         (lsign*(axl*v2->oz-byl*v2->oy-cl) > 0.0  &&
  2035.          rsign*(axr*v2->oz-byr*v2->oy-cr) < 0.0) ||
  2036.         (lsign*(axl*v0->oz-byl*v0->oy-cl) > 0.0  &&
  2037.          rsign*(axr*v0->oz-byr*v0->oy-cr) < 0.0))
  2038.       PolygonViewList[j++]=i;
  2039.  
  2040.     if ((lsign*(axl*v1->oz-byl*v1->oy-cl) < 0.0 ||
  2041.          lsign*(axl*v2->oz-byl*v2->oy-cl) < 0.0 ||
  2042.          lsign*(axl*v0->oz-byl*v0->oy-cl) < 0.0 ) &&
  2043.         (rsign*(axr*v1->oz-byr*v1->oy-cr) > 0.0 ||
  2044.          rsign*(axr*v2->oz-byr*v2->oy-cr) > 0.0 ||
  2045.          rsign*(axr*v0->oz-byr*v0->oy-cr) > 0.0 ) &&
  2046.         (fsign*(axf*v1->oz-byf*v1->oy-cf) < 0.0 ||
  2047.          fsign*(axf*v2->oz-byf*v2->oy-cf) < 0.0 ||
  2048.          fsign*(axf*v0->oz-byf*v0->oy-cf) < 0.0 ))
  2049.     {
  2050.       PolygonViewList[j++]=i;
  2051.     }
  2052.  
  2053.     /*
  2054.     if (fsign*(axf*v1->oz-byf*v1->oy-cf) < 0.0 ||
  2055.         fsign*(axf*v2->oz-byf*v2->oy-cf) < 0.0 ||
  2056.         fsign*(axf*v0->oz-byf*v0->oy-cf) < 0.0 )
  2057.     {
  2058.       PolygonViewList[j++]=i;
  2059.       printf("FRONT\n");
  2060.     }*/
  2061.           
  2062.   }
  2063.   NumOfViewedPolygons=j;
  2064. }
  2065.  
  2066.  
  2067. void
  2068. CalcViewTriangle(double cx, double cy, int theta)
  2069. {
  2070.   /* hmm step back a bit...
  2071.   double mcx,mcy;
  2072.   cx = -10.5*dcosine[theta]+cx;
  2073.   cy = -10.5*dsine[theta]+cy; */
  2074.  
  2075.   /* Set up left and right view edges */
  2076.   rtheta = (theta+(MAXDEGREES-FOV))%MAXDEGREES;
  2077.   ltheta = (theta+FOV)%MAXDEGREES;
  2078.   ftheta = (theta+(MAXDEGREES/4))%MAXDEGREES;
  2079.  
  2080.   /* Line Equation = */
  2081.   if (qabs(256-ltheta)>128 &&  /* nearer x-axis */
  2082.       qabs(768-ltheta)>128)
  2083.   {
  2084.     axl = polar_lut[ltheta]; byl = 1.0; cl  = (cx*axl-cy);
  2085.   }
  2086.   else
  2087.   {
  2088.     axl= 1.0; byl = polar_lut[ltheta]; cl  = (cx - cy*byl);
  2089.   }
  2090.  
  2091.   if (qabs(256-rtheta)>128 &&  /* nearer x-axis */
  2092.       qabs(768-rtheta)>128)
  2093.   {
  2094.     axr = polar_lut[rtheta]; byr = 1.0; cr  = (cx*axr-cy);
  2095.   }
  2096.   else
  2097.   {
  2098.     axr = 1.0; byr = polar_lut[rtheta]; cr  = (cx - cy*byr);
  2099.   }
  2100.  
  2101.   if (qabs(256-ftheta)>128 &&  /* nearer x-axis */
  2102.       qabs(768-ftheta)>128)
  2103.   {
  2104.     axf = polar_lut[ftheta]; byf = 1.0; cf  = (cx*axf-cy);
  2105.   }
  2106.   else
  2107.   {
  2108.     axf = 1.0; byf = polar_lut[ftheta]; cf  = (cx - cy*byf);
  2109.   }
  2110.  
  2111.   tpx = 10.0*dcosine[theta]+cx;
  2112.   tpy = 10.0*dsine[theta]+cy;
  2113.  
  2114.   if (axl*tpx-byl*tpy-cl > 0.0) lsign = 1.0;
  2115.   else lsign = -1.0;
  2116.  
  2117.   if (axr*tpx-byr*tpy-cr < 0.0) rsign = 1.0;
  2118.   else rsign = -1.0;
  2119.  
  2120.   if (axf*tpx-byf*tpy-cf < 0.0) fsign = 1.0;
  2121.   else fsign = -1.0;
  2122. }
  2123.  
  2124.  
  2125.  
  2126.  
  2127.  
  2128.  
  2129.